package com.yhou.demo.search.demo.impl;

import com.alibaba.fastjson.JSON;
import com.yhou.demo.search.demo.DemoServie;
import com.yhou.demo.search.demo.dto.DemoDTO;
import com.yhou.demo.search.enums.SearchTypeEnum;
import com.yhou.demo.search.esbase.AbstractESHandler;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.WildcardQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


/**
 * @author houyong
 * @ProjectName search
 * @Description:
 * @date 2018/09/06 下午2:59
 */
@Slf4j
@Component
public class DemoServiceImpl extends AbstractESHandler implements DemoServie {
    public DemoServiceImpl() {
        super(SearchTypeEnum.DemoSearch.getIndex(), SearchTypeEnum.DemoSearch.getType(),DemoDTO.class );
    }

    @Override
    public <T> boolean insert(T model) {
        DemoDTO demoDTO = (DemoDTO) model;
        log.info("DemoServiceImpl | insert | 创建文档 ：{}", demoDTO);
        IndexResponse response = client.prepareIndex(SearchTypeEnum.DemoSearch.getIndex(),
                SearchTypeEnum.DemoSearch.getType(), String.valueOf(demoDTO.getId()))
                .setSource(generateIndexObject(demoDTO))
                .get();
        if (response.getResult() == DocWriteResponse.Result.CREATED ||
                response.getResult() == DocWriteResponse.Result.UPDATED ||
                response.getResult() == DocWriteResponse.Result.NOOP) {
            log.info("SearchItemServiceImpl | insert | 创建Item 文档信息索引成功! Item={},response={}", demoDTO, response.getResult());
            return true;
        }
        return false;
    }

    @Override
    public <T> boolean update(T model) {
        return false;
    }



    /**
     * 使用QueryBuilder
     * termQuery("key", obj) 完全匹配
     * termsQuery("key", obj1, obj2..)   一次匹配多个值
     * matchQuery("key", Obj) 单个匹配, field不支持通配符, 前缀具高级特性
     * multiMatchQuery("text", "field1", "field2"..);  匹配多个字段, field有通配符忒行
     * matchAllQuery();         匹配所有文件
     */
    @Override
    public <T> List<T> select(T model) {
        DemoDTO demoDTO = (DemoDTO) model;


        SearchRequestBuilder searchRequestBuilder = client.prepareSearch(SearchTypeEnum.DemoSearch.getIndex())
                .setTypes(SearchTypeEnum.DemoSearch.getType());


        WildcardQueryBuilder wildcardQueryBuilder=QueryBuilders.wildcardQuery("name", "*" + demoDTO.getName() + "*");
        searchRequestBuilder.setQuery(wildcardQueryBuilder);
        SearchResponse searchResponse = searchRequestBuilder.setSize(100).execute().actionGet();
        log.info("==========>  "+searchRequestBuilder.toString());
        SearchHit[] hits = searchResponse.getHits().getHits();
        List<DemoDTO> demoDTOS = parseHits2Class(hits, DemoDTO.class);

        Arrays.stream(hits).forEach(hit->{
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            log.info("#######"+ sourceAsMap.get("id") +"#######");
            log.info("#######"+ sourceAsMap.get("name") +"#######");
        });
        log.info("结果 ： {}",JSON.toJSONString(hits));
        return null;
    }

    @Override
    public XContentBuilder generateIndexMapping() {
        // 创建mapping
        XContentBuilder builder = null;
        try {
            builder = XContentFactory.jsonBuilder()
                    .startObject()
                    //index name
                    .startObject(SearchTypeEnum.DemoSearch.getType())
                    .startObject("properties")

                    .startObject("id").field("type","long").endObject()
                    .startObject("name").field("type","keyword").field("index",true).endObject()
                    .startObject("age").field("type","keyword").endObject()

                    .endObject()
                    .endObject()
                    .endObject();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return builder;
    }
}
